Add @VersionColumn() to the entity — TypeORM auto-increments it on every save. If the version in the incoming update does not match the database version, TypeORM throws OptimisticLockVersionMismatchError. The QueryBuilder approach checks version in the WHERE clause and inspects affected rows to detect conflicts.
@VersionColumn() stores an integer that TypeORM increments on every save automatically.
If the incoming version does not match the DB version, TypeORM throws OptimisticLockVersionMismatchError.
Map OptimisticLockVersionMismatchError to ConflictException (409) in a global exception filter.
The client must send the version back with every update request — include it in the DTO.
Optimistic locking is best for low-contention scenarios; use pessimistic locking for high-contention fields.